#ifndef ZYGCYCLICLINKEDLIST_H
#define ZYGCYCLICLINKEDLIST_H

#include<QDebug>

template <typename T>
class ZygLinkedListNode
{
private:
    T* data;
    ZygLinkedListNode* next;

public:
    ZygLinkedListNode(){}

    ZygLinkedListNode(T* data,ZygLinkedListNode<T>* next = nullptr){
        this->data = data;
        this->next = next;
    }

    ~ZygLinkedListNode(){
        delete this->data;
    }


    T* getData(){
        return this->data;
    }

    void setData(T* data){
        this->data = data;
    }

    ZygLinkedListNode<T>* getNext()
    {
        return this->next;
    }

    void setNext(ZygLinkedListNode<T>* next){
        this->next = next;
    }
};

template <typename T>
class ZygClicLinkedList
{
private:
    ZygLinkedListNode<T>* head;
    ZygLinkedListNode<T>* rear;
    int size;
public:

    ZygClicLinkedList(){
        this->size = 0;
        this->head = nullptr;
        this->rear = nullptr;
    }

    ~ZygClicLinkedList(){

    }

    void append(T* data){
        ZygLinkedListNode<T>* node = new ZygLinkedListNode<T>(data);

        if(this->size == 0)
        {
            this->head = node;
        }
        else
        {
            this->rear->setNext(node);
        }
        this->rear = node;
        this->rear->setNext(this->head);
        this->size++;
    }

    bool addSort(T* data){
        if(data == nullptr) {
            return false;
        }
        ZygLinkedListNode<T>* node = new ZygLinkedListNode<T>(data);

        if(0 == this->size){
            this->head = node;
            this->rear = node;
            node->setNext(node);
            this->size++;
            data->createAlarmClock();
            return true;
        }

        ZygLinkedListNode<T>* current = this->head;

        //第二次循环插入
        do{
            //找到相同的不操作
            if((*data) == current->getData()){
                delete node;
                return true;
            }
            //要插入数据大于找到的数据,并且小于下一个数据
            if((*data) > current->getData() && (*data) < current->getNext()->getData()){
                node->setNext(current->getNext());
                current->setNext(node);
                this->size++;
                data->createAlarmClock();
                return true;;
            }
            current = current->getNext();
        }while(current != head);

        // 这个数据比当前所有数据都要小
        if((*data) < current->getData()){
            this->rear->setNext(node);
            node->setNext(this->head);
            this->head = node;
        }else{
            //这个数据最大
            node->setNext(this->head);
            this->rear->setNext(node);
            this->rear = node;
        }
        data->createAlarmClock();

        size++;
        return true;
    }

    T* get(int index){
        if(index > this->size - 1)
        {
            return nullptr;
        }
        ZygLinkedListNode<T>* current = this->head;
        for (int i = 0; i < index; i++)
        {
            current = current->getNext();
        }
        return current->getData();
    }

    int length(){
        return this->size;
    }

    void remove(T* data){
        if(this->size == 0){
            return;
        }
        ZygLinkedListNode<T>* current = this->head;
        do{
            if(*(current->getNext()) == data){
                if(this->size == 1){
                    delete this->rear;
                    this->head = nullptr;
                    this->rear = nullptr;
                    this->size = 0;
                    return;
                }
                ZygLinkedListNode<T>* deleteNode = current->getNext();
                current->setNext(deleteNode->getNext());
                delete deleteNode;
            }
            current = current->getNext();
        }while(current != this->head);
    }

    void remove(int index){
        if(index > this->size - 1)
        {
            return;
        }
        if(this->size == 1){
            delete this->rear;
            this->size = 0;
            this->head = nullptr;
            this->rear = nullptr;
            return;
        }
        if(index == 0) {
            ZygLinkedListNode<T>* deleteNode = this->head;
            this->head = deleteNode->getNext();
            this->rear->setNext(this->head);
            delete  deleteNode;
            this->size--;
            return;
        }
        ZygLinkedListNode<T>* current = this->head;
        for (int i = 0; i <= index - 2; i++)
        {
            if(current == nullptr)
            {
                return;
            }
            current = current->getNext();
        }

        ZygLinkedListNode<T>* deleteNode = current->getNext();
        ZygLinkedListNode<T>* newNext = deleteNode->getNext();
        current->setNext(newNext);
        delete  deleteNode;
        this->size--;
    }

    T* operator[](int index){
        return this->get(index);
    }

    void forEachPrint(){
        ZygLinkedListNode<T>* current = this->head;
        if(current == nullptr){
            return;
        }
        do{
            qDebug() << current->getData()->toString();
            current = current->getNext();
        }while(current != this->head);

    }

    void clear(){
        while (this->size > 0) {
            this->remove(0);
        }
    }

    QString toFormatString(){
        QString res = "";
        if(0 == this->size){
            return res;
        }
        ZygLinkedListNode<T>* current = this->head;
        do{
            res += current->getData()->toFormatString();
            current = current->getNext();
        }while(current != this->head);
        return res;
    }

};

#endif // ZYGCYCLICLINKEDLIST_H
